#include <iostream>
#include <pthread.h>
#include <unistd.h>
using namespace std;

#define THREAD_NUM 5
class ThreadData
{
public:
    ThreadData(const std::string &n, pthread_mutex_t *pm)
        : tname(n), pmtx(pm)
    {
    }

public:
    std::string tname;
    pthread_mutex_t *pmtx;
};
// 加锁保护
// pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER;
int tickets = 10000; // 临界资源

void *threadRoutine(void *args)
{
    ThreadData *td = (ThreadData *)args;
    //(void)args;
    while (true)
    {
        pthread_mutex_lock(td->pmtx); // 哪里的资源需要加锁保护，哪里就加锁
        if (tickets > 0)
        {
            usleep(1000);
            printf("%s:%d\n", td->tname.c_str(), tickets);
            tickets--;
            pthread_mutex_unlock(td->pmtx);
        }
        else
        {
            // 解锁
            pthread_mutex_unlock(td->pmtx);
            break;
        }
    }
    delete td;
    pthread_exit(nullptr);
    /*int i = 10;
    while (i--)
    {
        cout << "线程: " << (char *)args << "running..." << endl;
        sleep(1);
        // int a = 100;
        // a /= 0;
    }*/
}

int main()
{
    pthread_mutex_t mtx; // 在函数内初始化一把锁
    pthread_mutex_init(&mtx, nullptr);
    pthread_t tid[THREAD_NUM];
    for (int i = 0; i < THREAD_NUM; i++)
    {
        std::string name = "Thread ";
        name += std::to_string(i + 1);
        ThreadData *td = new ThreadData(name, &mtx);
        pthread_create(tid + i, nullptr, threadRoutine, (void *)td);
    }
    // 主线程等待所有线程
    for (int i = 0; i < THREAD_NUM; i++)
    {
        pthread_join(tid[i], nullptr);
    }
    pthread_mutex_destroy(&mtx);

    // pthread_create(&tid, nullptr, threadRoutine, (void *)"thread 1");

    // void *ret = nullptr;
    //  线程等待，获取线程退出信息
    // pthread_join(tid, &ret);
    // cout << "主线程 等待成功,收到返回值为：" << (long long)ret << endl;
    /*while (true)
    {
        cout << "main线程： "
             << "running... " << endl;
        sleep(1);
    }*/
}